home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-06-03 | 34.4 KB | 1,505 lines | [TEXT/MPS ] |
- /*************************************************************************************
- *
- * Create an Offscreen GWorld, Randomize and Sort it
- *
- * GWorld.cp - C Source
- *
- * Copyright © Apple Computer, Inc. 1988 - 1993
- * All rights reserved.
- *
- * This is the "meat" of the SortPicts program. This file supplies the
- * core functionality to SortPicts by overiding and supplementing
- * the WindowObj class.
- *
- *************************************************************************************/
-
- #include "GWorldObj.h"
- #include <stdio.h>
-
- Boolean gSetWTitleOK; // This is program wide so that DragHook can get to it!
- // Is it OK to set the Title? False during DragWindow!!
- pascal Boolean AboutBoxFilter( DialogPtr dialog, EventRecord *event, short *itemHit);
-
- #ifndef __powerc
- pascal void DragHookForThreads( void);
- #endif
-
- pascal void *GWorldThreadEntry( void *there);
-
- pascal void XDrawDragRgn( void);
- RgnHandle gDragRgnHandle; // You wouldn't believe me if I told you... but Watch this guy!
- GrafPtr gDragPort; // These are used to Hide and Show the Drag Rgn
- PenState gDragPen; // Just before a CopyBits action!! (Can you believe how skanky that is??)
- Boolean gDragRgnHandleValid; // Is the DragRgnHandle really a drag RgnHandle?
-
- #ifndef __powerc
- RgnHandle ReturnA3( void) = {0x204B, 0x200B};
- // = 0x200B; // MOVE.L A3,D0
- // & 0x204B // MOVE.L A3,A0 -- support for Metro•Werks
- #endif
-
-
- Boolean GWorldObj::BeginNewThread( void)
- {
- OSErr errWhatErr;
-
-
- if( gHasThreads)
- {
- errWhatErr = NewThread( kCooperativeThread,
- GWorldThreadEntry,
- (void *)this,
- 100000,
- kFPUNotNeeded + kCreateIfNeeded,
- (void**)nil,
- &threadInfo);
-
- if( errWhatErr != noErr)
- return false;
- else
- return true; // Successful new thread running!!
- }
- }
-
-
- pascal void *GWorldThreadEntry( void *there) // it's really "this" here
- {
- GWorldObj *object = (GWorldObj *)there;
-
- object->doneSorting = false;
- object->ScramblePict();
-
- switch( object->gSortAlgorithm)
- {
- case iShellSort:
- object->ShellSort();
- break;
- case iHeapSort:
- object->HeapSort();
- break;
- case iQuickSort:
- object->QuickSort();
- break;
-
- case iRandomSort:
- switch( object->RandomPixel(3) +1)
- {
- case iShellSort:
- object->ShellSort();
- break;
- case iHeapSort:
- object->HeapSort();
- break;
- case iQuickSort:
- object->QuickSort();
- break;
- }
- default:
- object->QuickSort();
- }
-
- object->threadInfo = 0;
- return nil;
- }
-
-
- /*************************************************************/
- /* */
- /* A Sort and Draw Help Routine */
- /* */
- /*************************************************************/
- void GWorldObj::SetSortItem( long index, long data)
- {
- long horiz, vert;
-
- horiz = index % pictWidth;
- vert = index / pictWidth;
-
- copyBitsRect.left = 0;
- copyBitsRect.right = pictWidth;
-
- if( vert >= copyBitsRect.bottom)
- copyBitsRect.bottom = (short) vert+1;
-
- if( vert < copyBitsRect.top)
- copyBitsRect.top = (short) vert;
-
- sortListPtr[index] = data;
- offset = horiz + (vert * pictRowBytes);
- offscreenPtr[offset] = (Byte)data;
- }
-
- void GWorldObj::ExchangeSortItem( long one, long theOther)
- {
- long temp;
-
- temp = sortListPtr[one];
- SetSortItem( one, sortListPtr[theOther]);
- SetSortItem( theOther, temp);
- }
-
-
- OSErr GWorldObj::YieldIfTime( char *mmuMode)
- {
- EventRecord tempEvent;
- long *tickPtr = (long *)0x16A;
-
- if( !yieldTime)
- {
- yieldTime = *tickPtr + gYieldDelay;
- return noErr;
- }
-
- if( *tickPtr >= yieldTime )
- {
- #ifndef DEMO
- UnuseGWorld();
- SwapMMUMode( mmuMode);
-
- SetPort( me);
- DrawObj();
-
- #endif
- if( gHasThreads == true)
- if( yieldOnlyToMe == false)
- YieldToAnyThread();
- else
- YieldToThread( kApplicationThreadID);
- else // No Threads package
- if( EventAvail( mDownMask + keyDownMask, &tempEvent) == true)
- {
- if( tempEvent.what == mouseDown)
- GetNextEvent( mDownMask + keyDownMask, &tempEvent);
- return memLockedErr;
- }
-
- SwapMMUMode( mmuMode);
- UseGWorld();
-
- #ifdef DEMO
- // f->osPixmap = ((CWindowPtr)me)->portPixMap;
- // f->pixels = (unsigned char *) GetPixBaseAddr( f->osPixmap);
- // f->osRowBytes = (**(f->osPixmap)).rowBytes & 0x3FFF;
- // f->pixels -= (long) ((**(f->osPixmap)).bounds.top * f->osRowBytes) + (**(f->osPixmap)).bounds.left;
- offscreenPtr -= (long) ((**(((CWindowPtr)me)->portPixMap)).bounds.top * pictRowBytes) +
- (**(((CWindowPtr)me)->portPixMap)).bounds.left;
- #endif
- yieldTime = *tickPtr + gYieldDelay;
- }
- return noErr;
- }
-
-
- void GWorldObj::UpdateObj( void)
- {
- Rect tempRect = copyBitsRect;
- Rect windowRect = windPictRect;
-
- copyBitsRect = worldPictRect;
- DrawObj();
- copyBitsRect = tempRect;
- }
-
- void GWorldObj::DrawObj( void)
- {
- Rect worldRect = copyBitsRect;
- Rect windowRect = windPictRect;
-
- #ifdef DEMO
- ValidRect( &windowRect);
- return;
- #endif
-
- XDrawDragRgn();
-
- SetPort( me);
- PenNormal();
-
- if( (gSetWTitleOK & needToUpdateWindowTitle) == true)
- {
- #ifndef DEMO
- SetWTitle( me, windowTitle);
- #endif
- needToUpdateWindowTitle = false;
- }
-
- if( randomizing == false)
- {
- if( gEraseWindow == true)
- EraseRect( &windowRect);
-
- if( gQualudesUpdate == false)
- { // This code sets CopyBits to do the right thing...
- SetRect( &windowRect, windPictRect.left,
- windPictRect.top + worldRect.top,
- windPictRect.left + pictWidth,
- windPictRect.top + worldRect.bottom);
- } // The Qualudes option tells copybits to do screwy things
-
- UseGWorld();
- SetPort( me);
-
- CopyBits( (const BitMap *) (*GetGWorldPixMap(sortGWorld)),
- (const BitMap *) (*GetGWorldPixMap((CGrafPtr) me)),
- &worldRect, &windowRect, srcCopy, (RgnHandle)0);
-
- UnuseGWorld();
-
- ValidRect( &windowRect);
-
- if( doneSorting == false)
- // Invert the top & bottom rect so that no drawing takes place!!
- // The sort algorithm expands this rect so that it is the smallest
- // that it needs to be to incorporate the bits modified
- SetRect( ©BitsRect, 0, 0x7FFF, pictWidth, -1);
- else
- copyBitsRect = worldPictRect;
- }
- else
- {
- short barWidth;
- short barHeight;
- short barLeftEdge;
- short barTopEdge;
- Rect barRect;
- PixPatHandle barPixPat = GetPixPat( 128);
-
- ValidRect( &windowRect);
- if( pictWidth >= 100)
- barWidth = 100;
- else
- barWidth = pictWidth - 10;
- barLeftEdge = windPictRect.left + ((pictWidth-barWidth) >> 1);
- if( pictHeight >= 20)
- barHeight = 12;
- else
- barHeight = pictHeight;
-
- if( pictHeight >= 100)
- barTopEdge = windPictRect.top + pictHeight-60;
- else
- barTopEdge = windPictRect.top + ((pictHeight-barHeight) >> 1);
-
-
- SetRect( &barRect, barLeftEdge, barTopEdge, barLeftEdge+barWidth, barTopEdge+barHeight);
- InsetRect( &barRect, -1, -1);
- FrameRect( &barRect);
- InsetRect( &barRect, 1, 1);
- barRect.right = barLeftEdge + (barWidth * percentComplete / 100);
- if( barPixPat)
- {
- FillCRect( &barRect, (PixPatHandle) barPixPat);
- DisposePixPat( barPixPat);
- }
- else
- PaintRect( &barRect);
-
- // Erase the right side of the rectangle
- if( percentComplete == 5)
- {
- barRect.left = barRect.right+1;
- barRect.right = barLeftEdge+barWidth;
- EraseRect( &barRect);
- }
- }
-
- XDrawDragRgn();
- }
-
-
- void GWorldObj::BackGroundObj( void)
- {
- if( gHasThreads == true)
- YieldToThread( threadInfo);
-
- if( (needToUpdateWindowTitle & gSetWTitleOK) == true)
- DrawObj();
-
- if( doneSorting == true && gContinuous == true)
- if( TickCount() > (gContinuousTime * 60 + finishedTime))
- MouseClickObj( (EventRecord *) 0);
- }
-
-
- void GWorldObj::IdleObj( void)
- {
- WindowPeek *firstWindow = (WindowPeek *) 0x9D6; // Start at the first window
- WindowPeek windowList = (WindowPeek) *firstWindow; // Walk the list
- GWorldObj *target;
- short windowCount;
-
- windowCount = 1;
- while( windowList)
- {
- target = (GWorldObj *)(windowList->refCon);
- if( windowCount++ == gNextBkgndWindowNum)
- {
- target->BackGroundObj();
- ++gNextBkgndWindowNum;
- return;
- }
- windowList = windowList->nextWindow;
- }
- // If we get here we obviously have a gNextBkgndWindowNum which is > than the number
- // of open windows. Therefore, set gNextBkgnd to 1 and send an update event to the
- // first window in the window list (if there is a first window)
- gNextBkgndWindowNum = 1;
- windowList = (WindowPeek) *firstWindow;
- if( windowList)
- {
- target = (GWorldObj *)(windowList->refCon);
- target->BackGroundObj();
- ++gNextBkgndWindowNum;
- }
- }
-
-
-
-
- /****************************************************************************/
- /* */
- /* Scramble Pict */
- /* */
- /****************************************************************************/
- void GWorldObj::ScramblePict( void)
- {
- long loop;
- RGBColor pixColor = {0, 0, 0};
- Byte pixelData;
- Byte *tOffscreenPtr;
- long horiz;
- long oneTwentieth;
- long loopTwentieth;
- short percentPerPiece = 5;
- long *tickPtr = (long *)0x16A;
- char mmuMode = true32b;
- #ifdef GenPictRects
- FILE *f;
- short bytesPerRow;
- char cPictName[32];
- short ci;
- #endif
-
- randomizing = true;
- percentComplete = 0;
- SetTitle( (const unsigned char*)"\pRandomizing");
- GetPort( &savePort);
-
- SetPort( me);
- pixColor.red = pixColor.blue = pixColor.green = 0;
- DrawObj();
-
- HLock( (Handle)sortList);
- sortListPtr = *sortList;
- // if( !sortListPtr)
- // DebugStr("\pScramble: sortListPtr == nil!");
-
- UseGWorld();
- // offscreenPtr = (Byte *)GetPixBaseAddr( sortGWorld->portPixMap);
- #ifdef DEMO
- offscreenPtr -= (long) ((**(((CWindowPtr)me)->portPixMap)).bounds.top * pictRowBytes) +
- (**(((CWindowPtr)me)->portPixMap)).bounds.left;
- #endif
- tOffscreenPtr = offscreenPtr;
-
- #ifdef GenPictRects
- cPictName[ci = pictureName[0]] = '\0';
- while( ci--)
- cPictName[ci] = pictureName[ci+1];
- f = fopen( "Sys:PictureRects", "w");
- if( !f)
- DebugStr( "\pERROR: File failed to open");
- fprintf( f, "NuRect %s = { %d, %d, %d, %d};\n", cPictName, me->portRect.left, me->portRect.top, me->portRect.right, me->portRect.bottom);
- fprintf( f, "char %s[] = {", cPictName);
- bytesPerRow = 16;
- #endif
-
- horiz = 0;
- SwapMMUMode( &mmuMode); // Switch to 32 bit mode for accessing pixels
-
- for( loop = 0; loop < N; ++loop)
- {
-
- pixelData = offscreenPtr[horiz];
- sortListPtr[loop] = ((long) pixelData) | loop << 8;
- ++horiz;
- if( horiz == pictWidth)
- {
- horiz = 0;
- offscreenPtr += pictRowBytes;
- }
- #ifdef GenPictRects
- SwapMMUMode( &mmuMode); // Switch back to make stupid calls
-
- fprintf( f, "0x%2.2X, ", (unsigned short) pixelData);
- if( !--bytesPerRow)
- {
- fprintf( f, "\n\t\t\t");
- fflush( f);
- bytesPerRow = 16;
- }
- SwapMMUMode( &mmuMode); // And switch again...
- #endif
- }
-
- SwapMMUMode( &mmuMode); // Switch back to x mode
-
- #ifdef GenPictRects
- fprintf( f, "};\n");
- fclose( f);
- #endif
-
- offscreenPtr = tOffscreenPtr;
-
- oneTwentieth = (N / 20) + 0;
- loopTwentieth = 0;
- yieldTime = TickCount() + gYieldDelay;
-
- SwapMMUMode( &mmuMode); // Switch to 32 bit mode for accessing pixels
-
- for( loop = N-1; loop > 1; --loop)
- {
- ExchangeSortItem( RandomPixel(loop), loop);
-
- ++loopTwentieth;
-
- if( loopTwentieth > oneTwentieth)
- {
- percentComplete += percentPerPiece;
- loopTwentieth = 0;
-
- if( TickCount() >= yieldTime)
- {
- SwapMMUMode( &mmuMode); // Switch back to mode X for other purposes
-
- UnuseGWorld();
- SetPort( me);
- DrawObj();
-
- if( yieldOnlyToMe == false)
- YieldToAnyThread();
- else
- YieldToThread( kApplicationThreadID);
-
- UseGWorld();
-
- #ifdef DEMO
- offscreenPtr -= (long) ((**(((CWindowPtr)me)->portPixMap)).bounds.top * pictRowBytes) +
- (**(((CWindowPtr)me)->portPixMap)).bounds.left;
- #endif
- yieldTime = TickCount() + gYieldDelay;
-
- SwapMMUMode( &mmuMode); // Switch into 32 bit mode, again
- }
- }
- }
-
- UnuseGWorld();
-
- SwapMMUMode( &mmuMode); // And now switch back to mode X
-
- SetPort( me);
- DrawObj();
-
- HUnlock( (Handle)sortList);
- randomizing = false;
- }
-
-
-
-
-
- /****************************************************************************/
- /* */
- /* Randomization Stuff */
- /* */
- /****************************************************************************/
- long GWorldObj::RandomPixel( long max) // Return a # between 0 <= x < max
- {
- long randomNum = 0x7FFFFFFF; // The ultimate long
- long tempN;
- short numNBits;
- short numShiftBits, numRandomBits;
-
- // Random Number Initialization
- tempN = max;
- numNBits = 1; // Using the additive conguential method (Random numbers)
- while (tempN >>= 1) // Count the number of bits required to hold N
- ++numNBits; // example: to hold 0x37 requires 6 bits (0-3F)
-
- numRandomBits = 31;
- numShiftBits = numRandomBits - numNBits;
-
- while( randomNum >= max)
- {
- // RandomNum generator
- randomNum = randomSeed = (randomSeed & 1) ^ ((randomSeed & (1L << 28)) >> 28)
- ? (randomSeed >> 1) : (randomSeed >> 1) | 0x40000000;
- // This next line "mixes" some of the upper bits with the lower bits
- randomNum = (randomNum >> numShiftBits) ^ (randomNum & (0x7FFFFFFF >> numShiftBits));
- }
-
- return randomNum;
- }
-
-
-
-
-
-
-
-
-
-
- /****************************************************************************/
- /* */
- /* Dumb Application */
- /* */
- /****************************************************************************/
-
- short GWorldObj::gSortSize;
- Boolean GWorldObj::gEraseWindow;
- Boolean GWorldObj::gHasThreads;
- Boolean GWorldObj::gQualudesUpdate;
- Boolean GWorldObj::gContinuous;
- short GWorldObj::gContinuousTime;
- Boolean GWorldObj::gSaveWindowPositions;
- short GWorldObj::gYieldDelay;
- short GWorldObj::gNumPictures;
- MenuHandle GWorldObj::gPicturesMenu;
- short GWorldObj::gWindOffSet;
- short GWorldObj::gNextBkgndWindowNum;
- short GWorldObj::gSortAlgorithm;
-
- void GWorldObj::InitObj( void)
- {
- long threadsPresentBit;
-
- // inherited::InitObj(); // This DOESN'T WORK IN MPW C++ ????
-
- isColor = gMac.hasColorQD; // Retain the color bit
- useActivateClicks = false; // Do not interpret activate events as action events
-
- // Set GWorldObj specific global variables
- gEraseWindow = false;
- gYieldDelay = 6;
- gSortSize = 0;
- gWindOffSet = 0;
- #ifdef DEMO
- gSetWTitleOK = false;
- #else
- gSetWTitleOK = true;
- #endif
- gDragRgnHandle = (RgnHandle) 0;
- gDragRgnHandleValid = false;
- gQualudesUpdate = false;
- gContinuous = true;
- gContinuousTime = 0;
- gSaveWindowPositions = false;
- gNextBkgndWindowNum = 1;
- gSortAlgorithm = iRandomSort; // default is a Random sort
-
- if( Gestalt( gestaltThreadMgrAttr, &threadsPresentBit) == noErr)
- gHasThreads = (1<<gestaltThreadMgrPresent) & threadsPresentBit ? true : false;
-
- // Build the Pictures Menu #PICTURESMENU
- gPicturesMenu = NewMenu( PICTURESMENU, (const unsigned char*)"\pPictures");
- AddResMenu( gPicturesMenu, 'PICT');
- InsertMenu( gPicturesMenu, -1);
-
- // Count the number of Pictures in the menu
- gNumPictures = CountMItems( gPicturesMenu);
-
- if( gHasThreads)
- {
- long *DragHook = (long *)0x09F6; // DragHook is called during DragWindow, etc.
- Handle startupPictStrHandle;
-
- #ifndef __powerc
- *DragHook = (long) DragHookForThreads; // Patch DragHook
- #endif
-
- startupPictStrHandle = GetNamedResource( 'STR#', (const unsigned char*)"\pStartup Pictures");
- if( startupPictStrHandle) // If there is a predefined list of startup pictures
- { // Load them in now
- short startupPictID;
- ResType tempType;
- Str255 tempName;
- Boolean newWindow = true;
- short windowCount = 1;
- GWorldObj *newObj;
-
- GetResInfo( startupPictStrHandle, &startupPictID, &tempType, tempName);
- while( newWindow == true)
- {
- newWindow = false; // Unless this window works, stop making them
- newObj = new GWorldObj;
- if( newObj)
- {
- GetIndString( newObj->pictureName, startupPictID, windowCount);
- if( newObj->pictureName[0])
- {
- newWindow = newObj->NewWindowObj(); // did this window work?
- }
- ++windowCount;
- YieldToAnyThread();
- }
- }
-
- }
- else // If there is no predefined list of pictures,
- { // just load in consecutive ones
- GWorldObj *a;
- Boolean newWindow = false;
- short windowCount;
-
- windowCount = 1;
- while( newWindow == true)
- {
- a = new GWorldObj;
- if( a)
- {
- GetItem( gPicturesMenu, windowCount, a->pictureName);
- newWindow = a->NewWindowObj();
- YieldToAnyThread();
- // RST: The following fix will force only one window to be created!
- newWindow = false;
- }
- ++windowCount;
- }
- }
- }
- else // gHasThreads == NOT!!
- {
- GWorldObj *a;
-
- a = new GWorldObj;
- if( a)
- {
-
- GetItem( gPicturesMenu, 1, a->pictureName);
- a->NewWindowObj();
- }
- }
- }
-
- Boolean GWorldObj::PrepareGWorld( void)
- {
- Rect worldRect;
- OSErr myOSErr;
- GWorldPtr myGWorld;
- GDHandle oldGDevice;
- CGrafPtr oldGWorld;
-
- // if( aboutBox)
- // return true;
-
- sortPict = (PicHandle)GetNamedResource( 'PICT', pictureName);
-
- if( sortPict == nil)
- return false;
-
- randomizing = true;
- percentComplete = 0;
- doneSorting = false;
- yieldOnlyToMe = false;
-
- worldPictRect = (*sortPict)->picFrame;
- pictWidth = worldPictRect.right - worldPictRect.left;
- pictHeight = worldPictRect.bottom - worldPictRect.top;
-
- SetRect( &worldPictRect, 0, 0, pictWidth, pictHeight);
- copyBitsRect = worldPictRect;
- windPictRect = worldPictRect;
- worldRect = worldPictRect;
-
- #ifdef DEMO
- if( !me)
- {
- ReleaseResource( (Handle)sortPict);
- return true;
- }
- #endif
-
- GetGWorld( &oldGWorld, &oldGDevice);
-
- myOSErr = NewGWorld( &myGWorld, 8, &worldRect, (CTabHandle) 0, (GDHandle)0, 0);
-
- if( myOSErr != noErr)
- {
- ReleaseResource( (Handle)sortPict);
- return false;
- }
-
- LockPixels( GetGWorldPixMap( myGWorld));
-
- #ifdef DEMO
- sortGWorld = (GWorldPtr) me;
- #else
- sortGWorld = myGWorld;
- #endif
-
- // f->osPixmap = ((CWindowPtr)me)->portPixMap;
- // f->pixels = (unsigned char *) GetPixBaseAddr( f->osPixmap);
- // f->osRowBytes = (**(f->osPixmap)).rowBytes & 0x3FFF;
- // f->pixels -= (long) ((**(f->osPixmap)).bounds.top * f->osRowBytes) + (**(f->osPixmap)).bounds.left;
-
- #ifdef DEMO
- pictRowBytes = 832;
- #else
- pictRowBytes = (*GetGWorldPixMap( sortGWorld))->rowBytes & 0x3FFF;
- #endif
- sortListSize = (long) pictWidth * (long) pictHeight ;
-
- sortList = (long **) NewHandle( sortListSize * sizeof(long) );
-
- if( sortList == nil)
- {
- ReleaseResource( (Handle)sortPict);
- DisposeGWorld( myGWorld);
- return false;
- }
-
- #ifdef DEMO
- GetGWorld( &oldGWorld, &oldGDevice);
- SetPort( (GrafPort*)sortGWorld);
- #else
- // GetGWorld( &oldGWorld, &oldGDevice);
- // SetGWorld( sortGWorld, nil);
- UseGWorld();
- #endif
-
- EraseRect( &worldRect);
- DrawPicture( sortPict, &worldRect);
-
- ReleaseResource( (Handle)sortPict);
-
- // SetGWorld( oldGWorld, oldGDevice);
- UnuseGWorld();
-
- return true; // YES!! The everything worked out!
- }
-
- Boolean GWorldObj::NewWindowObj( void)
- {
- Rect winRect;
- Handle winRectHandle;
- Point midPoint;
-
- me = nil;
- sortGWorld = nil;
- needToUpdateWindowTitle = false;
- windowTitle[0] = '\0';
- savedCount = 0;
-
- aboutBox = false;
-
- if( PrepareGWorld() == true)
- {
- windPictRect = worldPictRect;
- winRect = windPictRect;
- sortAlgorithm = gSortAlgorithm;
- randomSeed = TickCount();
- yieldTime = 0;
-
- OffsetRect( &winRect, 40 + gWindOffSet, 40 + gWindOffSet);
- gWindOffSet += 40;
- if( gWindOffSet >= 300)
- gWindOffSet = 0;
-
- winRectHandle = GetNamedResource( 'RECT', pictureName);
- if( winRectHandle)
- {
- winRect = **((Rect**)winRectHandle);
- ReleaseResource( winRectHandle);
- }
-
- midPoint.h = winRect.left + ((winRect.right - winRect.left)>>1);
- midPoint.v = winRect.top + ((winRect.bottom - winRect.top)>>1);
- #ifdef __CONDITIONALMACROS__
- if( !PtInRgn( midPoint, LMGetGrayRgn()))
- #else
- if( !PtInRgn( midPoint, *(RgnHandle *)GrayRgn))
- #endif
- {
- DebugStr( (const unsigned char*)"\pWindow's not on the screen!!\n");
- }
-
- me = NewCWindow( NIL, &winRect, (ConstStr255Param)"\pLoading", true, noGrowDocProc, (WindowPtr)-1, true,
- /* CRITICALLY IMPORTANT:: */ (long) this);
-
- if( winRectHandle)
- ReleaseResource( winRectHandle);
-
- if( me) /* Do these things if the window was created ! */
- {
- ((WindowPeek)me)->windowKind = WindowObjKind;
-
- if( !sortGWorld)
- PrepareGWorld();
-
- if( BeginNewThread() == true)
- {
- return true;
- }
- DisposeWindow( me);
- DisposeGWorld( sortGWorld);
- DisposeHandle( (Handle)sortList);
- return false;
- }
- else // me == nil
- return false;
- }
- else
- return false;
- }
-
-
- Boolean GWorldObj::AboutObj( void)
- {
- char **pictName = (char **)GetResource( 'STR ', ABOUTPICTURENAMEID);
- short loop;
- short itemType;
- Handle itemHandle;
- Rect itemRect;
- short itemHit;
-
- sortGWorld = nil;
- needToUpdateWindowTitle = false;
- windowTitle[0] = '\0';
- savedCount = 0;
-
- if( pictName)
- {
- // Copy the picture name string from the Handle to this->pictureName
- for( loop = pictureName[0] = (*pictName)[0]; loop ; --loop)
- pictureName[loop] = (*pictName)[loop];
-
- ReleaseResource( (Handle)pictName);
-
- aboutBox = true;
- me = nil;
-
- if( PrepareGWorld() == true)
- {
- me = (WindowPtr) GetNewDialog( ABOUTDIALOG, (Ptr) 0, (WindowPtr) -1);
- if( me)
- {
- ((WindowPeek)me)->refCon = (long)this;
- GetDItem( (DialogPtr) me, ABOUTDIALOGPICT, &itemType, &itemHandle, &itemRect);
- windPictRect = itemRect;
-
- if( gHasThreads)
- {
- if( BeginNewThread() == true)
- {
- #ifdef __powerc
- AboutBoxFilterUPP = NewModalFilterProc( (long (*)(void))AboutBoxFilter);
- #endif
- itemHit = -1;
- while( itemHit != 1)
- {
- #ifdef __powerc
- ModalDialog( AboutBoxFilterUPP, &itemHit);
- #else
- ModalDialog( AboutBoxFilter, &itemHit);
- #endif
- }
-
- if( threadInfo != 0)
- DisposeThread( threadInfo, 0, false);
- #ifdef __powerc
- if( AboutBoxFilterUPP)
- DisposePtr( (Ptr) AboutBoxFilterUPP);
- #endif
- }
- }
- else
- {
- itemHit = -1;
-
- // First, allow the redraw algorithm to kick in
- for( loop = 0; loop < 3 && itemHit == -1; loop ++)
- #ifdef __powerc
- ModalDialog( (class RoutineDescriptor*)0, &itemHit);
- #else
- ModalDialog( (ModalFilterProcPtr)0, &itemHit);
- #endif
-
- // Randomize and Sort the picture
- if( itemHit == -1)
- BeginNewThread();
-
- // Now wait for the user to quit this dialog
- while( itemHit != 1)
- #ifdef __powerc
- ModalDialog( (class RoutineDescriptor*)0, &itemHit);
- #else
- ModalDialog( (ModalFilterProcPtr)0, &itemHit);
- #endif
- }
-
- DisposeDialog( (DialogPtr) me);
- me = (WindowPtr)0;
- }
-
- DisposeHandle( (Handle)sortList);
- DisposeGWorld( sortGWorld);
- return false;
- }
- else
- {
- return false;
- }
- }
- return false;
- }
-
- pascal Boolean AboutBoxFilter( DialogPtr dialog, EventRecord *event, short *itemHit)
- {
- GWorldObj *object = (GWorldObj *)((WindowPeek)dialog)->refCon;
- GWorldObj *target;
- WindowPtr whichWindow;
- short windowPart;
-
- if( (event->what == keyDown) &&
- ( ((event->message & charCodeMask) == 13) || // Test for RETURN key
- ((event->message & charCodeMask) == 3 ) ) ) // Test for ENTER key
- {
- *itemHit = 1;
- return true;
- }
-
- if( event->what == mouseDown)
- {
- windowPart = FindWindow( event->where, &whichWindow);
- if( whichWindow == object->me && windowPart == inDrag)
- {
- object->DragWindowObj( event);
- return true;
- }
- }
-
- if( event->what == updateEvt)
- {
- target = (GWorldObj *)((WindowPeek)event->message)->refCon;
-
- target->UpdateObj();
- if( target == object)
- return false;
- return true;
- }
-
- if( event->what == nullEvent)
- object->IdleObj();
-
- return false;
- }
-
-
-
- void GWorldObj::AdjustMenusObj( void)
- {
- Str255 yieldDelayStr;
- Str255 yieldDelayMenuStr;
- MenuHandle userOptionsMenu = GetMHandle( USEROPTIONSMENU);
- MenuHandle sortAlgorithmMenu = GetMHandle( mSortAlgorithm);
- short yieldDMLen, numStrLen;
- MenuHandle menu;
-
- menu = GetMHandle( mFile); // Do the File menu first
- if( menu)
- {
- EnableItem(menu, iNew); // Enable the items, one at a time...
- EnableItem(menu, iOpen);
- if( me != NIL)
- {
- EnableItem(menu, iClose);
- }
- else
- {
- DisableItem(menu, iClose);
- }
-
- DisableItem(menu, iSave);
- DisableItem(menu, iSaveAs);
- DisableItem(menu, iRevert);
- DisableItem(menu, iPageSetup);
- DisableItem(menu, iPrint);
- EnableItem(menu, iQuit);
- }
-
- menu = GetMHandle( mEdit);
- if( menu)
- {
- DisableItem(menu, iUndo);
- DisableItem(menu, iCut);
- DisableItem(menu, iCopy);
- DisableItem(menu, iClear);
- DisableItem(menu, iPaste);
- }
-
- if( userOptionsMenu)
- {
- NumToString( gYieldDelay, yieldDelayStr);
- GetItem( userOptionsMenu, UO_SHOWTTYDELAY, yieldDelayMenuStr);
- yieldDMLen = yieldDelayMenuStr[0];
- while( yieldDelayMenuStr[yieldDMLen] != ' ')
- yieldDMLen--;
-
- numStrLen = yieldDelayStr[0];
- yieldDelayMenuStr[0] = yieldDMLen + numStrLen;
- while( numStrLen)
- {
- yieldDelayMenuStr[yieldDMLen + numStrLen] = yieldDelayStr[numStrLen];
- numStrLen--;
- }
- SetItem( userOptionsMenu, UO_SHOWTTYDELAY, yieldDelayMenuStr);
- CheckItem( userOptionsMenu, UO_ERASE, gEraseWindow);
- CheckItem( userOptionsMenu, UO_QUALUDES, gQualudesUpdate);
- CheckItem( userOptionsMenu, UO_CONTINUOUS5Sec, gContinuous && (gContinuousTime == 5));
- CheckItem( userOptionsMenu, UO_CONTINUOUS0Sec, gContinuous && (gContinuousTime == 0));
- CheckItem( userOptionsMenu, UO_SAVEWINDPOS, gSaveWindowPositions);
- CheckItem( userOptionsMenu, UO_SORT_0, gSortSize == 0);
- CheckItem( userOptionsMenu, UO_SORT_1, gSortSize == 1);
- }
-
- if( sortAlgorithmMenu)
- {
- CheckItem( sortAlgorithmMenu, iShellSort, gSortAlgorithm == iShellSort);
- CheckItem( sortAlgorithmMenu, iHeapSort , gSortAlgorithm == iHeapSort );
- CheckItem( sortAlgorithmMenu, iQuickSort , gSortAlgorithm == iQuickSort );
- CheckItem( sortAlgorithmMenu, iRandomSort , gSortAlgorithm == iRandomSort );
- }
- }
-
-
-
-
-
- void GWorldObj::MenuObj( short menuID, short menuItem, EventRecord *event)
- {
- WINDOWOBJ *a;
- Str255 daName;
-
- switch( menuID )
- {
- case mApple:
- if( menuItem == iAbout)
- {
- WINDOWOBJ *a;
- a = new WINDOWOBJ;
- if( a)
- {
- a->AboutObj();
- delete a;
- }
- }
- else // Open a desk accessory...
- {
- GetItem(GetMHandle(mApple), menuItem, daName);
- (void) OpenDeskAcc(daName);
- }
- break;
- case mFile:
- switch( menuItem)
- {
- case iClose:
- CloseWindowObj();
- break;
- case iPageSetup:
- PageSetupObj();
- break;
- case iPrint:
- PrintObj();
- break;
- default:
- AppMenu( menuID, menuItem); // This is like inheritance!!
- break;
- }
- break;
-
- case USEROPTIONSMENU:
- switch( menuItem)
- {
- case UO_ERASE: // Erase Window User Option
- gEraseWindow = !gEraseWindow;
- break;
- case UO_QUALUDES: // Alter the CopyBits behavior
- gQualudesUpdate = !gQualudesUpdate;
- break;
- case UO_CONTINUOUS5Sec: // Run for ever
- case UO_CONTINUOUS0Sec: // Run for ever, fast!
- if( gContinuous)
- gContinuous = (gContinuousTime == 5 && menuItem == UO_CONTINUOUS5Sec) ||
- (gContinuousTime == 0 && menuItem == UO_CONTINUOUS0Sec)
- ? false : true;
- else
- gContinuous = true;
- gContinuousTime = (UO_CONTINUOUS5Sec == menuItem) ? 5 : 0;
- break;
- case UO_SAVEWINDPOS:// Run for ever
- gSaveWindowPositions = !gSaveWindowPositions;
- break;
- case UO_SORT_0: // Complete the Sort 100%
- gSortSize = 0;
- break;
- case UO_SORT_1: // Finish 1 step before the sort is complete
- gSortSize = 1;
- break;
- case UO_BLANK: // This is a dividing line
- break;
- case UO_SHOWTTYDELAY: // This displays the Time To Yield
- break;
- case UO_DECREASETTY: // Decrease Time To Yield Delay
- if( gYieldDelay > 5)
- gYieldDelay -= 4;
- break;
- case UO_INCREASETTY: // Increase Time To Yield Delay
- gYieldDelay += 4;
- break;
- }
- break;
-
- case PICTURESMENU:
- a = new WINDOWOBJ;
- if( a)
- {
- GetItem( gPicturesMenu, menuItem, a->pictureName);
- if( a->NewWindowObj() == false)
- delete a;
- }
- break;
-
- case mSortAlgorithm:
- gSortAlgorithm = menuItem;
- break;
-
- default:
- if( (event->message & charCodeMask) == 'n')
- {
- WINDOWOBJ *a;
- a = new WINDOWOBJ;
- if( a)
- {
- MenuHandle gPicturesMenu = GetMHandle( PICTURESMENU);
-
- if( gPicturesMenu)
- {
- GetItem( gPicturesMenu, (short)(((short)(TickCount()) & 0x7FFF) % a->gNumPictures), a->pictureName);
- if( a->NewWindowObj() == false)
- delete a;
- }
- }
- }
- else if( ((event->message & charCodeMask) == ',') ||
- ((event->message & charCodeMask) == '<') )
- {
- if( a->gYieldDelay > 5)
- a->gYieldDelay -= 4;
- }
- else if( ((event->message & charCodeMask) == '.') ||
- ((event->message & charCodeMask) == '>') )
- gYieldDelay += 4;
- else if( ((event->message & charCodeMask) >= '1') &&
- ((event->message & charCodeMask) <= '0') )
- {
- WINDOWOBJ *a;
- a = new WINDOWOBJ;
- if( a)
- {
- MenuHandle gPicturesMenu = GetMHandle( PICTURESMENU);
-
- if( gPicturesMenu)
- {
- GetItem( gPicturesMenu, (short)(event->message & charCodeMask) - '0', a->pictureName);
- if( a->NewWindowObj() == false)
- delete a;
- }
- }
- }
- else
- AppMenu( menuID, menuItem); // This is like inheritance!!
- break;
- }
- HiliteMenu(0);
- }
-
-
-
-
- void GWorldObj::GrowWindowObj( EventRecord *event)
- {
- // This window doesn't grow...
- int a = 0;
- if( a != 0)
- event->modifiers = 0;
- }
-
- void GWorldObj::MouseClickObj( EventRecord *event)
- {
- Rect worldRect, windRect;
- EventRecord *cpEvent = event; // Gets CFront off my back!
-
- if( doneSorting == true)
- {
- randomizing = true;
- percentComplete = 0;
- doneSorting = false;
-
- sortPict = (PicHandle)GetNamedResource( 'PICT', pictureName);
-
- if( sortPict)
- {
- #ifndef DEMO
- SetPort( me);
- worldRect = worldPictRect;
- windRect = windPictRect;
- EraseRect( &windRect);
-
- // GetGWorld( &oldGWorld, &oldGDevice);
- // SetGWorld( sortGWorld, (GDHandle)0);
- UseGWorld();
-
- EraseRect( &worldRect);
- DrawPicture( sortPict, &worldRect);
-
- ReleaseResource( (Handle)sortPict);
-
- UnuseGWorld();
- // SetGWorld( oldGWorld, oldGDevice);
- #endif
- BeginNewThread();
- }
- }
- else
- {
- Str255 oldWindowTitle;
- Str255 tempTitle;
- Str255 turboTitle = "\pTurbo";
- Boolean equal;
- short loop;
-
- GetWTitle( me, oldWindowTitle);
- SetTitle( turboTitle);
- yieldOnlyToMe = true;
-
- while( StillDown() && (doneSorting == false))
- {
- YieldToThread( threadInfo);
- GetWTitle( me, tempTitle);
- equal = true;
- for( loop = 0; (loop <= tempTitle[0]) && (equal == true); ++loop)
- equal = (tempTitle[loop] == turboTitle[loop]);
- if( equal == false)
- {
- GetWTitle( me, oldWindowTitle);
- SetTitle( turboTitle);
- }
- }
-
- yieldOnlyToMe = false;
- SetTitle( oldWindowTitle);
- }
- }
-
- Boolean GWorldObj::CloseWindowObj( void)
- {
- if( me == FrontWindow())
- {
- if( gHasThreads && threadInfo != 0)
- DisposeThread( threadInfo, 0, false);
- DisposeHandle( (Handle)sortList);
- DisposeGWorld( sortGWorld);
- DisposeWindow( me); // Call the Mac to eliminate the window!
-
- return true;
- }
- else
- return false;
-
- }
-
- void GWorldObj::DrawGrowIconObj( void)
- {
- // Don't draw the grow thing!
- }
-
-
- void GWorldObj::DragWindowObj( EventRecord *event)
- {
- Rect globalWindRect; // global as in desk top, not program wise
- Point *tempPoint;
- Handle rsrcRect;
- GrafPtr savedPort;
-
- gDragRgnHandleValid = true;
-
- WindowObj::DragWindowObj( event);
-
- gDragRgnHandleValid = false;
-
- if( gSaveWindowPositions == true)
- {
- // Create a RECT within the Actual application which is the RECT of the Window's
- // Global portRect. OK? But remove this code before it ships (because it's sick
- // to ship code which modifies its own file!!).
-
- GetPort( &savedPort);
- SetPort( me);
-
- globalWindRect = me->portRect;
- tempPoint = (Point *)&globalWindRect;
- LocalToGlobal( tempPoint);
- globalWindRect.right += globalWindRect.left;
- globalWindRect.bottom += globalWindRect.top;
-
- rsrcRect = GetNamedResource( 'RECT', pictureName);
- if( rsrcRect)
- {
- HLock( rsrcRect);
- **((Rect **) rsrcRect) = globalWindRect;
- HUnlock( rsrcRect);
- ChangedResource( rsrcRect);
- }
- else // resource didn't load in
- {
- rsrcRect = NewHandle( sizeof(Rect)); // 8 bytes
- if( rsrcRect)
- {
- HLock( rsrcRect);
- **((Rect **) rsrcRect) = globalWindRect;
- HUnlock( rsrcRect);
- AddResource( rsrcRect, 'RECT', UniqueID( 'RECT'), pictureName);
- }
- }
- SetPort( savedPort);
- }
- }
-
-
- /*
- *
- * This code is 68K specific ...
- */
-
- #ifndef __powerc
-
- pascal void DragHookForThreads( void)
- {
- gDragRgnHandle = ReturnA3();
-
- GetPenState( &gDragPen);
- GetPort( &gDragPort);
- gSetWTitleOK = false;
-
- YieldToAnyThread();
-
- gDragRgnHandle = (RgnHandle) 0;
- #ifndef DEMO
- gSetWTitleOK = true;
- #endif
- SetPort( gDragPort);
- SetPenState( &gDragPen);
- }
-
- pascal void XDrawDragRgn( void)
- {
- GrafPtr savedPort;
- PenState savedPen;
- short **firstRgnWord;
-
- if( gDragRgnHandle && gDragRgnHandleValid)
- {
- GetPenState( &savedPen);
- GetPort( &savedPort);
-
- SetPort( gDragPort);
- SetPenState( &gDragPen);
-
- firstRgnWord = (short **)gDragRgnHandle;
- if( **firstRgnWord == 0x000A)
- FrameRect( (Rect *) &((*firstRgnWord)[1]));
- else
- PaintRgn( gDragRgnHandle);
-
- SetPort( savedPort);
- SetPenState( &savedPen);
- }
- }
-
- #else
-
- /*
- * This code is PowerPC filler ...
- */
-
- pascal void DragHoodForThreads( void)
- {
- // empty PowerPC routines
- }
-
- pascal void XDrawDragRgn( void)
- {
-
- }
-
- #endif
- void GWorldObj::SetTitle( ConstStr255Param title)
- {
- short loop;
-
- if( gSetWTitleOK == true)
- {
- #ifndef DEMO
- SetWTitle( me, title);
- #endif
- needToUpdateWindowTitle = false;
- }
- else
- needToUpdateWindowTitle = true;
-
- loop = windowTitle[0] = title[0];
- while( loop)
- {
- windowTitle[loop] = title[loop];
- --loop;
- }
- }
-
-
- void GWorldObj::UseGWorld( void)
- {
- PixMapHandle offscreenPixMapHndl;
-
- if( !savedCount++)
- {
- GetGWorld( &savedPort, &savedGDH);
-
- offscreenPixMapHndl = GetGWorldPixMap( sortGWorld);
-
- LockPixels( offscreenPixMapHndl);
-
- offscreenPtr = (Byte *) GetPixBaseAddr( offscreenPixMapHndl);
-
- SetGWorld( sortGWorld, (GDHandle) 0);
- }
- }
-
- void GWorldObj::UnuseGWorld( void)
- {
- PixMapHandle offscreenPixMapHndl;
-
- if( !--savedCount)
- {
- offscreenPixMapHndl = GetGWorldPixMap( sortGWorld);
-
- // UnlockPixels( offscreenPixMapHndl);
-
- offscreenPtr = (Byte *) -1;
-
- SetGWorld( savedPort, savedGDH);
- }
- }
-
-